package com.jeesite.modules.task.deploy.service;

import com.jeesite.common.collect.ListUtils;
import com.jeesite.common.config.Global;
import com.jeesite.common.entity.Page;
import com.jeesite.common.idgen.IdGen;
import com.jeesite.common.lang.ObjectUtils;
import com.jeesite.common.lang.StringUtils;
import com.jeesite.common.service.CrudService;
import com.jeesite.common.service.ServiceException;
import com.jeesite.common.utils.excel.ExcelImport;
import com.jeesite.common.validator.ValidatorUtils;
import com.jeesite.modules.backlog.service.DcSupBacklogService;
import com.jeesite.modules.common.service.SysOfficeUnitService;
import com.jeesite.modules.file.dao.FileUploadDao;
import com.jeesite.modules.file.entity.FileUpload;
import com.jeesite.modules.file.utils.FileUploadUtils;
import com.jeesite.modules.msg.entity.content.PcMsgContent;
import com.jeesite.modules.msg.utils.MsgPushUtils;
import com.jeesite.modules.sys.entity.Office;
import com.jeesite.modules.sys.utils.DictUtils;
import com.jeesite.modules.sys.utils.UserUtils;
import com.jeesite.modules.task.action.dao.DcSupTaskActionDao;
import com.jeesite.modules.task.action.entity.DcSupTaskAction;
import com.jeesite.modules.task.audit.service.DcSupTaskAuditService;
import com.jeesite.modules.task.deploy.dao.DcSupTaskInfoAddDao;
import com.jeesite.modules.task.deploy.dao.DcSupTaskInfoDao;
import com.jeesite.modules.task.deploy.dao.DcSupTaskInfoRefineDao;
import com.jeesite.modules.task.deploy.entity.DcSupTaskInfo;
import com.jeesite.modules.task.deploy.entity.DcSupTaskInfoAdd;
import com.jeesite.modules.task.deploy.entity.DcSupTaskInfoRefine;
import com.jeesite.modules.task.deploy.entity.OfficeUser;
import com.jeesite.modules.task.dict.entity.DcSupTaskInfoDict;
import com.jeesite.modules.task.dict.service.DcSupTaskInfoDictService;
import com.jeesite.modules.task.feedback.dao.DcSupTaskFeedbackDao;
import com.jeesite.modules.task.feedback.entity.DcSupTaskFeedback;
import com.jeesite.modules.task.status.service.DcSupTaskStatusService;
import com.jeesite.modules.utils.Dict;
import com.jeesite.modules.utils.OfficeUtil;
import com.jeesite.modules.yzw.entity.MsgDetail;
import com.jeesite.modules.yzw.service.LehandYzwPushTask;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 任务部署信息表-记录细化分解信息 dao
 *
 * @author ya_jun
 */
@Service
@Transactional(readOnly=false)
public class DcSupTaskInfoRefineService extends CrudService<DcSupTaskInfoRefineDao, DcSupTaskInfoRefine> {
    @Autowired
    private SysOfficeUnitService sysOfficeUnitService;
    @Autowired
    @Lazy
    private DcSupTaskAuditService dcSupTaskAuditService;
    @Autowired
    private DcSupTaskInfoDao dcSupTaskInfoDao;
    @Autowired
    private DcSupTaskInfoAddDao dcSupTaskInfoAddDao;
    @Autowired
    private DcSupTaskActionDao dcSupTaskActionDao;
    @Autowired
    private DcSupTaskStatusService dcSupTaskStatusService;
    @Resource
    private FileUploadDao fileUploadDao;
    @Autowired
    private DcSupTaskFeedbackDao dcSupTaskFeedbackDao;
    @Autowired
    private LehandYzwPushTask lehandYzwPushTask;
    @Autowired
    private DcSupTaskInfoDictService dcSupTaskInfoDictService;
    @Autowired
    private DcSupBacklogService dcSupBacklogService;

    @Override
    public DcSupTaskInfoRefine get(DcSupTaskInfoRefine entity) {
        DcSupTaskInfoRefine refine = super.get(entity);
        if (refine != null) {
            DcSupTaskInfoAdd dcSupTaskInfoAdd = new DcSupTaskInfoAdd();
            dcSupTaskInfoAdd.setTaskId(refine.getTaskId());
            dcSupTaskInfoAdd.setTaskRefineId(refine.getId());
            refine.setDcSupTaskInfoAddList(dcSupTaskInfoAddDao.findList(dcSupTaskInfoAdd));
        }
        return refine;
    }

    /**
     * 保存任务数据
     *
     * @param dcSupTaskInfo
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveTask(DcSupTaskInfo dcSupTaskInfo) {
        // 初始化一些字段值
        dcSupTaskInfo.setCreateOrg(OfficeUtil.getCurrentOffice().getOfficeCode());
        dcSupTaskInfo.setCreateOrgName(OfficeUtil.getCurrentOffice().getOfficeName());
        dcSupTaskInfo.setDecomposeFlag("0");
        dcSupTaskInfo.setParentTaskId("0");
        dcSupTaskInfo.setSourceTaskId("0");

        Office latestUnit = sysOfficeUnitService.getLatestUnitByOffice();
        dcSupTaskInfo.setCreateUnit(latestUnit.getOfficeCode());
        dcSupTaskInfo.setCreateUnitName(latestUnit.getOfficeName());

        if (StringUtils.isNotBlank(dcSupTaskInfo.getAuditorCode())) {
            dcSupTaskInfo.setAuditFlag("1");
        }

        if (dcSupTaskInfo.getIsNewRecord()) {
            dcSupTaskInfoDao.insert(dcSupTaskInfo);
        } else {
            dcSupTaskInfoDao.update(dcSupTaskInfo);
        }

        dcSupTaskStatusService.addStatus(dcSupTaskInfo.getId(), Dict.StatusTargetType.TAG_1, dcSupTaskInfo.getTaskStatus(),
                DictUtils.getDictLabel(Dict.TaskStatus.DICT_TYPE, dcSupTaskInfo.getTaskStatus(), "未知"));

        // 1是草稿，如果不是1，就要考虑发布任务或者创建审核数据
        if (!Dict.TaskStatus.STATUS_1.equals(dcSupTaskInfo.getTaskStatus())) {
            // 如果没有指定审核人，则不审核
            if (StringUtils.isBlank(dcSupTaskInfo.getAuditorCode())) {
                // 创建细化分解数据
                generateRefine(dcSupTaskInfo);
                //3细任务部署，向所有牵头单位的【任务收文员】角色用户发送消息，让确认分阶段目标
                Thread thread = new Thread(() -> {
                    String [] orgs = dcSupTaskInfo.getTaskLeaderOrg().split(",");
                    for (int i = 0; i < orgs.length; i++) {
                        List<OfficeUser> userByOrg = dcSupTaskActionDao.getUserByOrg("OTSTRANSFER",orgs[i]);
                        for (OfficeUser user: userByOrg) {
//                            PcMsgContent msg = new PcMsgContent();
//                            msg.setTitle("提示信息");
//                            msg.setContent("您有一个任务:\""+dcSupTaskInfo.getTaskTitle()+"\"的分阶段目标待报送,请及时查看");
//                            msg.addButton("分阶段报送", "/a/taskdeploy/dcSupTaskInfoRefine/refineList");
//                            MsgPushUtils.push(msg, dcSupTaskInfo.getId() + "_" + orgs[i], "confirm_refine", user.getUserCode());
                            //发送易政网消息
                            MsgDetail msgDetail = new MsgDetail();
                            msgDetail.setSendid(UserUtils.getUser().getUserCode());
                            msgDetail.setSubjectid(user.getUserCode());
                            msgDetail.setMesg("您有一个任务:\""+dcSupTaskInfo.getTaskTitle()+"\"分阶段目标待报送,请及时登录系统查看");
                            lehandYzwPushTask.pushYzwShortMsg(msgDetail);
                        }
                        //新增待办
                        dcSupBacklogService.addOffice("督查督办","任务阶段目标报送","任务阶段目标报送","提示信息"
                                ,"您有一个任务:"+dcSupTaskInfo.getTaskTitle()+"的分阶段目标待报送,请及时查看"
                                ,"/a/taskdeploy/dcSupTaskInfoRefine/refineList",orgs[i]
                                ,dcSupTaskInfo.getId(),"task_refine",userByOrg
                                ,dcSupTaskInfo.getId(),"");
                    }
                });
                thread.start();

            } else {
                // 设置一个临时变量来记录这条任务放到审核表中时的id，在消息中使用
                String tempAuditId = IdGen.nextId();
                String secretary_general = dcSupTaskAuditService.addAuditInfo(tempAuditId, dcSupTaskInfo.getId(), dcSupTaskInfo.getId(), Dict.TargetType.TYPE_1, Dict.AuditType.TYPE_7,
                        dcSupTaskInfo.getAuditorCode(), dcSupTaskInfo.getAuditorName(), null);
                if (StringUtils.isNotBlank(secretary_general)) {
                    throw new ServiceException("创建过程审核失败");
                }
                // 1细任务部署，选择审核人，向审核人发送消息
//                PcMsgContent msg = new PcMsgContent();
//                msg.setTitle("提示信息");
//                // 任务部署
//                msg.setContent("您有一个任务:\""+dcSupTaskInfo.getTaskTitle()+"\"细化任务部署待审核,请及时查看");
//                msg.addButton("任务部署审核", "/a/audit/dcSupTaskAudit/form?id=" + tempAuditId);
//                MsgPushUtils.push(msg, tempAuditId, "audit_deploy", dcSupTaskInfo.getAuditorCode());
                //发送易政网消息
                MsgDetail msgDetail = new MsgDetail();
                msgDetail.setSendid(UserUtils.getUser().getUserCode());
                msgDetail.setSubjectid(dcSupTaskInfo.getAuditorCode());
                msgDetail.setMesg("您有一个任务:\""+dcSupTaskInfo.getTaskTitle()+"\"细化任务部署待审核,请及时登录系统查看查看");
                lehandYzwPushTask.pushYzwShortMsg(msgDetail);
                //新增待办
                dcSupBacklogService.add("督查督办","任务部署审核","细化分解任务部署审核","提示信息"
                        ,"您有一个任务:" + dcSupTaskInfo.getTaskTitle() + "任务部署待审核,请及时查看"
                        ,"/a/audit/dcSupTaskAudit/form?id="+tempAuditId,""
                        ,tempAuditId,"task_audit_deploy",dcSupTaskInfo.getAuditorCode()
                        ,dcSupTaskInfo.getId(),"");
                //置为已办
                dcSupBacklogService.doBacklog(dcSupTaskInfo.getId(),"task_deploy");
                // 指定审核人时，反馈时间设置相当于保存为草稿的状态，在审核确认后会使用到这个数据
                saveTaskAddTime(dcSupTaskInfo);
            }
        } else {
            // 草稿状态，保存数据时不关联任务分解id
            saveTaskAddTime(dcSupTaskInfo);
        }

        // 保存上传图片
        FileUploadUtils.saveFileUpload(dcSupTaskInfo, dcSupTaskInfo.getId(), "dcSupTaskInfo_image");
        // 保存上传附件
        FileUploadUtils.saveFileUpload(dcSupTaskInfo, dcSupTaskInfo.getId(), "dcSupTaskInfo_file");
    }

    /**
     * 创建细化分解数据
     *
     * @param dcSupTaskInfo
     */
    @Transactional(rollbackFor = Exception.class)
    public void generateRefine(DcSupTaskInfo dcSupTaskInfo) {
        String feedbackWay = dcSupTaskInfo.getFeedbackWay();
        String feedbackRate = dcSupTaskInfo.getFeedbackRate();
        if (StringUtils.isBlank(feedbackWay) || (StringUtils.isBlank(feedbackRate)&&!feedbackWay.equals("4"))) {
            throw new ServiceException("反馈方式和反馈频次不可为空！");
        }

        String org = dcSupTaskInfo.getTaskLeaderOrg();
        String orgName = dcSupTaskInfo.getTaskLeaderOrgName();
        String[] orgs = org.split(",");
        String[] orgNames = orgName.split(",");
        List<DcSupTaskInfoRefine> refineList = new ArrayList<>();
        for (int i = 0; i < orgs.length; i++) {
            DcSupTaskInfoRefine refine = new DcSupTaskInfoRefine();
            refine.setTaskId(dcSupTaskInfo.getId());
            refine.setTaskLeaderOrg(orgs[i]);
            refine.setTaskLeaderOrgName(orgNames[i]);
            refine.setFeedbackRate(dcSupTaskInfo.getFeedbackRate());
            refine.setFeedbackWay(dcSupTaskInfo.getFeedbackWay());
            refineList.add(refine);
        }
        this.dao.insertBatch(refineList);
        saveTaskAddTime(dcSupTaskInfo, refineList);
    }

    /**
     * 任务分解确认
     *
     * @param taskInfoRefine
     */
    @Transactional(rollbackFor = Exception.class)
    public void refine(DcSupTaskInfoRefine taskInfoRefine) {
        if (ListUtils.isEmpty(taskInfoRefine.getDcSupTaskInfoAddList())) {
            throw new ServiceException("反馈开始结束时间不可为空！");
        }
        taskInfoRefine.setAuditStatus("0");
        // 更新细化分解数据
        this.save(taskInfoRefine);
        // 保存反馈时间设置
        saveTaskAddTime(taskInfoRefine);

        DcSupTaskInfo dcSupTaskInfo = dcSupTaskInfoDao.get(new DcSupTaskInfo(taskInfoRefine.getTaskId()));
        // 生成审核数据，指定审核人为任务创建人
        // 设置一个临时变量来记录这条任务放到审核表中时的id，在消息中使用
        String tempAuditId = IdGen.nextId();
        String secretaryGeneral = dcSupTaskAuditService.addAuditInfo(tempAuditId, taskInfoRefine.getId(), taskInfoRefine.getTaskId(), Dict.TargetType.TYPE_4, Dict.AuditType.TYPE_8,
                dcSupTaskInfo.getCreateBy(), UserUtils.get(dcSupTaskInfo.getCreateBy()).getUserName(), null);
        if (StringUtils.isNotBlank(secretaryGeneral)) {
            throw new ServiceException("创建过程审核失败");
        }
        // 4细收文员提交确认目标后，向任务部署人发送消息，通知审核目标
//        PcMsgContent msg = new PcMsgContent();
//        msg.setTitle("提示信息");
//        msg.setContent("您有一个任务:\""+dcSupTaskInfo.getTaskTitle()+"\"已确认，待审核,请及时查看");
//        msg.addButton("任务细化分解审核", "/a/audit/dcSupTaskAudit/form?id=" + tempAuditId);
//        MsgPushUtils.push(msg, tempAuditId, "audit_confirm", dcSupTaskInfo.getCreateBy());
        //发送易政网消息
        MsgDetail msgDetail = new MsgDetail();
        msgDetail.setSendid(UserUtils.getUser().getUserCode());
        msgDetail.setSubjectid(dcSupTaskInfo.getCreateBy());
        msgDetail.setMesg("您有一个任务:\""+dcSupTaskInfo.getTaskTitle()+"\"已确认，待审核,请及时登录系统查看");
        lehandYzwPushTask.pushYzwShortMsg(msgDetail);
        //新增待办
        dcSupBacklogService.add("督查督办","任务细化分解审核","任务细化分解审核","提示信息"
                ,"您有一个任务:\""+dcSupTaskInfo.getTaskTitle()+"\"已确认，待审核,请及时查看"
                , "/a/audit/dcSupTaskAudit/form?id=" + tempAuditId,taskInfoRefine.getTaskLeaderOrg()
                ,tempAuditId,"task_audit_confirm",dcSupTaskInfo.getCreateBy()
                ,dcSupTaskInfo.getId(),"");
        dcSupBacklogService.doBacklog(dcSupTaskInfo.getId(),"task_refine",taskInfoRefine.getTaskLeaderOrg());
    }

    /**
     * 保存反馈时间设置
     * 保存草稿时执行
     *
     * @param dcSupTaskInfo
     */
    private void saveTaskAddTime(DcSupTaskInfo dcSupTaskInfo) {
        DcSupTaskInfoAdd add = new DcSupTaskInfoAdd();
        add.setTaskId(dcSupTaskInfo.getId());
        dcSupTaskInfoAddDao.deleteByEntity(add);
        List<DcSupTaskInfoAdd> addList = dcSupTaskInfo.getDcSupTaskInfoAddList();
        addList.forEach(l -> {
            if (ObjectUtils.isEmpty(l.getFeedbackStartTime()) || ObjectUtils.isEmpty(l.getFeedbackEndTime())) {
                throw new ServiceException("反馈开始时间和反馈结束时间不能为空！");
            }
            l.setId(null);
            l.setTaskId(dcSupTaskInfo.getId());
            dcSupTaskInfoAddDao.insert(l);
        });
    }

    /**
     * 保存反馈时间设置
     * 生成分解数据时执行
     *
     * @param dcSupTaskInfo
     * @param refineList
     */
    private void saveTaskAddTime(DcSupTaskInfo dcSupTaskInfo, List<DcSupTaskInfoRefine> refineList) {
        DcSupTaskInfoAdd add = new DcSupTaskInfoAdd();
        add.setTaskId(dcSupTaskInfo.getId());
        dcSupTaskInfoAddDao.deleteByEntity(add);

        refineList.forEach(refine -> {
            List<DcSupTaskInfoAdd> list = dcSupTaskInfo.getDcSupTaskInfoAddList();
            list.forEach(l -> {
                if (ObjectUtils.isEmpty(l.getFeedbackStartTime()) || ObjectUtils.isEmpty(l.getFeedbackEndTime())) {
                    throw new ServiceException("反馈开始时间和反馈结束时间不能为空！");
                }
                l.setId(null);
                l.setTaskId(refine.getTaskId());
                l.setTaskRefineId(refine.getId());
            });
            dcSupTaskInfoAddDao.insertBatch(list);
        });
    }

    /**
     * 保存反馈时间设置
     * 分解确认时执行
     *
     * @param taskInfoRefine
     */
    private void saveTaskAddTime(DcSupTaskInfoRefine taskInfoRefine) {
        DcSupTaskInfoAdd taskInfoAdd = new DcSupTaskInfoAdd();
        taskInfoAdd.setTaskRefineId(taskInfoRefine.getId());
        dcSupTaskInfoAddDao.deleteByEntity(taskInfoAdd);
        List<DcSupTaskInfoAdd> list = taskInfoRefine.getDcSupTaskInfoAddList();
        list.forEach(l -> {
            if (StringUtils.isBlank(l.getFeedbackRequire())) {
                throw new ServiceException("未指定反馈要求！");
            }
            l.setId(null);
            l.setTaskId(taskInfoRefine.getTaskId());
            l.setTaskRefineId(taskInfoRefine.getId());
        });
        dcSupTaskInfoAddDao.insertBatch(list);
    }

    /**
     * 查询分解确认列表分页数据
     *
     * @param dcSupTaskInfo
     * @return
     */
    public Page<DcSupTaskInfoRefine> findRefinePage(DcSupTaskInfo dcSupTaskInfo) {
        Page<DcSupTaskInfo> page = dcSupTaskInfo.getPage();
        List<DcSupTaskInfoRefine> refineList = findRefineList(dcSupTaskInfo);
        Page<DcSupTaskInfoRefine> resultPage = new Page<>(page.getPageNo(), page.getPageSize(), page.getCount(), refineList);
        return resultPage;
    }
    public Page<DcSupTaskInfoRefine> queryRefineUpdateListData(DcSupTaskInfo dcSupTaskInfo) {
        Page<DcSupTaskInfo> page = dcSupTaskInfo.getPage();
        List<DcSupTaskInfoRefine> refineList = dao.queryRefineUpdateListData(dcSupTaskInfo);
        Page<DcSupTaskInfoRefine> resultPage = new Page<>(page.getPageNo(), page.getPageSize(), page.getCount(), refineList);
        return resultPage;
    }

    /**
     * 查询分解确认列表数据
     *
     * @param dcSupTaskInfo
     * @return
     */
    public List<DcSupTaskInfoRefine> findRefineList(DcSupTaskInfo dcSupTaskInfo) {
        dcSupTaskInfo.setCreateBy(UserUtils.getUser().getUserCode());
        List<DcSupTaskInfoRefine> refineList = this.dao.findRefineList(dcSupTaskInfo);
        refineList.forEach(refine -> {
            refine.setDcSupTaskInfo(dcSupTaskInfoDao.get(new DcSupTaskInfo(refine.getTaskId())));
            if(StringUtils.equals(refine.getAuditStatus(),"2")){
                refine.setAuditOption(dao.getAuditOpt(refine.getId()));
            }
        });
        return refineList;
    }

    /**
     * 发布任务
     * 细化分解审核通过后执行
     *
     * @param taskRefineId 分解id
     */
    @Transactional(rollbackFor = Exception.class)
    public void distributeOrgTask(String taskRefineId) {
        Assert.hasText(taskRefineId, "细化分解id不能为空！");

        DcSupTaskInfoRefine taskInfoRefine = this.get(taskRefineId);
        DcSupTaskInfo dcSupTaskInfo = dcSupTaskInfoDao.get(new DcSupTaskInfo(taskInfoRefine.getTaskId()));

        // 发布任务
        DcSupTaskAction dcSupTaskAction = generateTaskAction(taskInfoRefine, dcSupTaskInfo);

        // 5细任务部署，分发任务时，向所有牵头单位的【任务收文员】角色用户发送消息
                List<OfficeUser> userByOrg = dcSupTaskActionDao.getUserByOrg("OTSTRANSFER",taskInfoRefine.getTaskLeaderOrg());
                for (OfficeUser user: userByOrg) {
//                    PcMsgContent msg = new PcMsgContent();
//                    msg.setTitle("提示信息");
//                    msg.setContent("您有一个任务:\""+dcSupTaskInfo.getTaskTitle()+"\"待签收,请及时查看");
//                    msg.addButton("任务接收", "/a/audit/taskReceive/list");
//                    MsgPushUtils.push(msg, dcSupTaskInfo.getId() + "_" + orgs[i], "distribute_deploy", user.getUserCode());
                    //发送易政网消息
                    MsgDetail msgDetail = new MsgDetail();
                    msgDetail.setSendid(UserUtils.getUser().getUserCode());
                    msgDetail.setSubjectid(user.getUserCode());
                    msgDetail.setMesg("您有一个任务:\""+dcSupTaskInfo.getTaskTitle()+"\"待签收,请及时登录系统查看");
                    lehandYzwPushTask.pushYzwShortMsg(msgDetail);
                }
            //新增待办
            dcSupBacklogService.addOffice("督查督办","任务接收","细化任务待接收","提示信息"
                    ,"您有一个任务:" + dcSupTaskInfo.getTaskTitle() + "待签收,请及时查看"
                    ,"/a/audit/taskReceive/list",taskInfoRefine.getTaskLeaderOrg()
                    ,dcSupTaskInfo.getId(),"task_receive",userByOrg
                    ,dcSupTaskInfo.getId(),dcSupTaskAction.getId());

        // 生成反馈数据
        generateFeedback(taskRefineId, dcSupTaskInfo, dcSupTaskAction);

        // 复制附件
        cpFileUpload(dcSupTaskInfo, dcSupTaskAction);
    }

    /**
     * 审核分解数据
     *
     * @param taskRefineId 分解id
     * @param auditStatus  审核状态（默认为空，1通过，0未通过）
     */
    @Transactional(rollbackFor = Exception.class)
    public void auditRefine(String taskRefineId, String auditStatus) {
        Assert.hasText(taskRefineId, "未指定分解id！");
        DcSupTaskInfoRefine refine = new DcSupTaskInfoRefine();
        refine.setId(taskRefineId);
        refine.setAuditStatus(auditStatus);
        this.dao.auditRefine(refine);
    }

    /**
     * 生成反馈数据
     */
    private void generateFeedback(String taskRefineId, DcSupTaskInfo dcSupTaskInfo, DcSupTaskAction dcSupTaskAction) {
        DcSupTaskInfoAdd taskInfoAdd = new DcSupTaskInfoAdd();
        taskInfoAdd.setTaskId(dcSupTaskInfo.getId());
        taskInfoAdd.setTaskRefineId(taskRefineId);
        List<DcSupTaskInfoAdd> taskInfoAddList = dcSupTaskInfoAddDao.findList(taskInfoAdd);
        taskInfoAddList.forEach(add -> {
            if (add.getFeedbackStartTime() != null && add.getFeedbackEndTime() != null) {
                DcSupTaskFeedback feedback = new DcSupTaskFeedback();
                feedback.setTaskId(dcSupTaskInfo.getId());
                feedback.setActionId(dcSupTaskAction.getId());
                feedback.setFeedbackEndTime(add.getFeedbackEndTime());
                feedback.setFeedbackStartTime(add.getFeedbackStartTime());
                feedback.setFeedbackStatus("-1");
                feedback.setFeedbackRequire(add.getFeedbackRequire());
                dcSupTaskFeedbackDao.insert(feedback);
                dcSupTaskStatusService.addStatus(feedback.getId(), Dict.StatusTargetType.TAG_3, feedback.getFeedbackStatus(),
                        DictUtils.getDictLabel("dc_feedback_status", feedback.getFeedbackStatus(), "未知"));
            }
        });
    }

    /**
     * 复制附件
     *
     * @param dcSupTaskInfo
     * @param dcSupTaskAction
     */
    private void cpFileUpload(DcSupTaskInfo dcSupTaskInfo, DcSupTaskAction dcSupTaskAction) {
        List<FileUpload> fileUploadList = FileUploadUtils.findFileUpload(dcSupTaskInfo.getId(), "dcSupTaskInfo_file");
        fileUploadList.forEach(fileUpload -> {
            fileUpload.setId(null);
            fileUpload.setBizKey(dcSupTaskAction.getId());
            fileUpload.setBizType("dcSupTaskAction_file");
            fileUploadDao.insert(fileUpload);
        });
    }

    /**
     * 发布任务
     *
     * @param taskInfoRefine
     * @param dcSupTaskInfo
     */
    private DcSupTaskAction generateTaskAction(DcSupTaskInfoRefine taskInfoRefine, DcSupTaskInfo dcSupTaskInfo) {
        DcSupTaskAction dcSupTaskAction = new DcSupTaskAction();
        dcSupTaskAction.setTaskId(dcSupTaskInfo.getId());
        dcSupTaskAction.setLeaderOrgCode(taskInfoRefine.getTaskLeaderOrg());
        dcSupTaskAction.setLeaderOrgName(taskInfoRefine.getTaskLeaderOrgName());
        dcSupTaskAction.setTransferFlag("0");
        dcSupTaskAction.setExplainFlag("0");
        dcSupTaskAction.setTaskStatus("1");
        dcSupTaskAction.setCreateBy(UserUtils.getUser().getUserCode());
        dcSupTaskAction.setCreateDate(new Date());
        dcSupTaskAction.setTaskProgress("3");
        dcSupTaskActionDao.insert(dcSupTaskAction);
        dcSupTaskStatusService.addStatus(dcSupTaskAction.getId(), Dict.StatusTargetType.TAG_2, dcSupTaskAction.getTaskStatus(),
                DictUtils.getDictLabel("dc_task_action_status", dcSupTaskAction.getTaskStatus(), "未知"));
        return dcSupTaskAction;
    }

    /**
     * 导入督办数据
     *
     * @param file
     * @return
     */
    @Transactional(readOnly = false)
    public String importData(MultipartFile file) {
        if (file == null) {
            throw new ServiceException(text("请选择导入的数据文件！"));
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        try (ExcelImport ei = new ExcelImport(file, 2, 0)) {
            List<DcSupTaskInfo> list = ei.getDataList(DcSupTaskInfo.class);
            for (DcSupTaskInfo info : list) {
                try {
                    // 验证数据文件
                    ValidatorUtils.validateWithException(info);
                    // 任务年度为空验证
                    if (StringUtils.isBlank(info.getTaskYear())) {
                        failureNum++;
                        failureMsg.append("<br/>" + failureNum + " 导入失败：任务年度不能为空");
                        continue;
                    }
                    if (StringUtils.isBlank(info.getTaskTypeName())) {
                        failureNum++;
                        failureMsg.append("<br/>" + failureNum + " 导入失败：任务类型不能为空");
                        continue;
                    }

                    if (StringUtils.isBlank(info.getTaskTitle())) {
                        failureNum++;
                        failureMsg.append("<br/>" + failureNum + " 导入失败：任务标题不能为空");
                        continue;
                    }
                    if (StringUtils.isBlank(info.getTaskContent())) {
                        failureNum++;
                        failureMsg.append("<br/>" + failureNum + " 导入失败：任务内容不能为空");
                        continue;
                    }
                    if (info.getTaskStartTime() == null) {
                        failureNum++;
                        failureMsg.append("<br/>" + failureNum + " 导入失败：反馈起始时间不能为空");
                        continue;
                    }
                    if (info.getTaskEndTime() == null) {
                        failureNum++;
                        failureMsg.append("<br/>" + failureNum + " 导入失败：反馈截止时间不能为空");
                        continue;
                    }
                    if (StringUtils.isBlank(info.getSortNum())) {
                        failureNum++;
                        failureMsg.append("<br/>" + failureNum + " 导入失败：排序编号不能为空");
                        continue;
                    }
                    String type = "";
                    DcSupTaskInfoDict dcSupTaskInfoDict = new DcSupTaskInfoDict();
                    dcSupTaskInfoDict.setDictStatus("0");
                    dcSupTaskInfoDict.setDictLabel(info.getTaskTypeName());
                    DcSupTaskInfoDict dcSupTaskInfoDict1 = dcSupTaskInfoDictService.getValue(dcSupTaskInfoDict);
                    if(dcSupTaskInfoDict1!=null){
                        type=dcSupTaskInfoDict1.getDictValue();
                    }
                    if (StringUtils.isBlank(type)) {
                        failureNum++;
                        failureMsg.append("<br/>" + failureNum + " 导入失败：系统没有此任务类型");
                        continue;
                    }
                    if (info.getContactName().length()>64) {
                        failureNum++;
                        failureMsg.append("<br/>" + failureNum + " 导入失败：联系人过长");
                        continue;
                    }
                    if(StringUtils.isNotBlank(info.getContactPhone())){
                        String regex = "^1[345678]\\d{9}$";
                        Pattern pattern = Pattern.compile(regex);
                        Matcher matcher = pattern.matcher(info.getContactPhone());
                        if (!matcher.matches()) {
                            failureNum++;
                            failureMsg.append("<br/>" + failureNum + " 导入失败：手机号码格式不正确");
                            continue;
                        }
                    }
                    // 验证是否存在这个用户
                    info.setTaskStatus(Dict.TaskStatus.STATUS_1);
                    info.setTaskTypeCode(type);
                    info.setNormalFlag("3");
                    // 获取当前会话对象
                    info.setCreateOrg(OfficeUtil.getCurrentOffice().getOfficeCode());
                    info.setCreateOrgName(OfficeUtil.getCurrentOffice().getOfficeName());
                    Office latestUnit = sysOfficeUnitService.getLatestUnitByOffice();
                    info.setCreateUnit(latestUnit.getOfficeCode());
                    info.setCreateUnitName(latestUnit.getOfficeName());
                    dcSupTaskInfoDao.insert(info);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、任务 " + info.getTaskTitle() + " 导入成功");

                } catch (Exception e) {
                    failureNum++;
                    String msg = "<br/>" + failureNum + "、任务 " + info.getTaskTitle() + " 导入失败：";
                    if (e instanceof ConstraintViolationException) {
                        ConstraintViolationException cve = (ConstraintViolationException) e;
                        for (ConstraintViolation<?> violation : cve.getConstraintViolations()) {
                            msg += Global.getText(violation.getMessage()) + " (" + violation.getPropertyPath() + ")";
                        }
                    } else {
                        msg += e.getMessage();
                    }
                    failureMsg.append(msg);
                    logger.error(msg, e);
                }
            }
        } catch (Exception e) {
            failureMsg.append(e.getMessage());
            logger.error(e.getMessage(), e);
        }
        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    /**
     * 生成分解进度
     *
     * @param dcSupTaskInfoList
     */
    public void generateRefineProgress(List<DcSupTaskInfo> dcSupTaskInfoList) {
        dcSupTaskInfoList.forEach(task -> {
            DcSupTaskInfoRefine refine = new DcSupTaskInfoRefine();
            refine.setTaskId(task.getId());
            // 全部分解数据
            long total = this.findCount(refine);
            // 已分解且审核通过的分解数据
            refine.setAuditStatus("1");
            long refined = this.findCount(refine);
            task.setRefineProgress(refined + "/" + total);
        });
    }

    public void doTransfer(DcSupTaskInfoRefine taskInfoRefine) {
        super.save(taskInfoRefine);
//        PcMsgContent msg = new PcMsgContent();
//        msg.setTitle("提示信息");
//        msg.addButton("任务阶段目标报送", "/a/taskdeploy/dcSupTaskInfoRefine/refineList");
//        msg.setContent("有一个任务阶段目标报送被分配给您!");
//        MsgPushUtils.push(msg, taskInfoRefine.getId(), "mubiaobaosongzhuanban", taskInfoRefine.getTransferCode());
        DcSupTaskInfoRefine dcSupTaskInfoRefine = super.get(taskInfoRefine.getId());
        System.out.println(dcSupTaskInfoRefine);

        dcSupBacklogService.updateBacklog(dcSupTaskInfoRefine.getTaskId(),"task_refine",dcSupTaskInfoRefine.getTaskLeaderOrg(),taskInfoRefine.getTransferCode());
    }

    public void refineDelete(String id) {
        dao.refineDelete(id);
    }
}
